﻿using System;
using System.Collections.Generic;
using System.Linq;
using Pap.Core.Utilities;
using Pap.Data;
using Pap.Data.Abstraction.Utils;
using Pap.Services;
using Pap.Web.Utils;

namespace Pap.Web.Modules.Loan.ViewModel
{
    /// <summary>
    /// 
    /// </summary>
    public class LoanSocialResearchDetailsViewModel : IViewModel
    {
        /// <summary>
        /// 
        /// </summary>
        ILoanRepository loanRepository;
        /// <summary>
        /// 
        /// </summary>
        IWorkflowService wfService;

        /// <summary>
        /// Initializes a new instance of the <see cref="LoanSocialResearchDetailsViewModel"/> class.
        /// </summary>
        /// <param name="loanRepo">The loan repo.</param>
        /// <param name="wf">The wf.</param>
        public LoanSocialResearchDetailsViewModel(ILoanRepository loanRepo, IWorkflowService wf)
        {
            this.loanRepository = loanRepo;
            this.wfService = wf;
        }

        /// <summary>
        /// Gets the customer from loan.
        /// </summary>
        /// <param name="CurrentLoanID">The current loan ID.</param>
        /// <returns></returns>
        public ICustomer GetCustomerFromLoan(string CurrentLoanID)
        {
            if (CurrentLoanID.IsNullOrEmpty() || CurrentLoanID.ToGuid() == Guid.Empty)
                return null;

            ICustomer cust = loanRepository.GetCustomerLoanByID(CurrentLoanID.ToGuid()).CustomerObj;
            return cust;
        }

        /// <summary>
        /// Gets the social research for loan.
        /// </summary>
        /// <param name="loanID">The loan ID.</param>
        /// <returns></returns>
        public ILoanSocialResearch GetSocialResearchForLoan(string loanID)
        {
            if (loanID.IsNullOrEmpty() || loanID.ToGuid() == Guid.Empty)
                return null;

            ILoanSocialResearch research = loanRepository.FindLoanSocialResearches(r => r.LoanID == loanID.ToGuid()).FirstOrDefault();
            return research;
        }

        /// <summary>
        /// Gets the loan.
        /// </summary>
        /// <param name="loanID">The loan ID.</param>
        /// <returns></returns>
        public ICustomerLoan GetLoan(string loanID)
        {
            return loanRepository.GetCustomerLoanByID(loanID.ToGuid());
        }

        /// <summary>
        /// Saves the social research.
        /// </summary>
        /// <param name="loanID">The loan ID.</param>
        /// <param name="attachmentIDs">The attachment I ds.</param>
        /// <param name="deletedImages">The deleted images.</param>
        /// <param name="familyNumber">The family number.</param>
        /// <param name="totalIncome">The total income.</param>
        /// <param name="notes">The notes.</param>
        /// <param name="actionTaken">The action taken.</param>
        /// <param name="completionDate">The completion date.</param>
        public void SaveSocialResearch(string loanID, IEnumerable<Guid> attachmentIDs, IEnumerable<Guid> deletedImages, int familyNumber,
            double totalIncome, string notes, Pap.Services.WorkflowEngine.ActionTypes actionTaken, DateTime? completionDate)
        {
            using (IUnitOfWork unit = this.GetInstance<IUnitOfWork>())
            {
                ILoanSocialResearch currentResearch = GetSocialResearchForLoan(loanID);
                bool isNew = false;
                if (currentResearch == null)
                {
                    isNew = true;
                    currentResearch = this.GetInstance<ILoanSocialResearch>();
                    currentResearch.SocialResearchDate = DateTime.Now;
                    currentResearch.LoanID = loanID.ToGuid();
                    currentResearch.LoanSocialResearchID = Guid.NewGuid();
                }

                currentResearch.FamilyNumbers = familyNumber;
                currentResearch.IncomeAmount = totalIncome;
                currentResearch.Notes = notes;

                if (isNew)
                    loanRepository.CreateLoanSocialResearch(currentResearch);

                // Move the workflow
                // if the action Accept then user will fill the feasability study and move the workflow

                if (actionTaken != Services.WorkflowEngine.ActionTypes.Accept)
                    TakeDecision(loanID.ToGuid(), actionTaken, notes, completionDate);

                // Save the attachments to DB

                foreach (var attachment in attachmentIDs)
                {
                    if (loanRepository.FindLoanSocialResearchAttachments(a => a.LoanSocialResearchID == currentResearch.LoanSocialResearchID && a.Attachment == attachment).Count() == 0)
                    {
                        ILoanSocialResearchAttachment att = this.GetInstance<ILoanSocialResearchAttachment>();
                        att.LoanSocialResearchAttachmentID = Guid.NewGuid();
                        att.LoanSocialResearchID = currentResearch.LoanSocialResearchID;
                        att.Attachment = attachment;

                        loanRepository.CreateLoanSocialResearchAttachment(att);
                    }
                }

                foreach (var imageID in deletedImages)
                {
                    ILoanSocialResearchAttachment att = loanRepository.FindLoanSocialResearchAttachments(a => a.Attachment == imageID).SingleOrDefault();
                    if (att != null)
                    {
                        loanRepository.DeleteLoanSocialResearchAttachment(att);
                    }
                }

                unit.Commit();
            }
        }

        /// <summary>
        /// Takes the decision.
        /// </summary>
        /// <param name="loanID">The loan ID.</param>
        /// <param name="actionTaken">The action taken.</param>
        /// <param name="notes">The notes.</param>
        /// <param name="completionDate">The completion date.</param>
        public void TakeDecision(Guid loanID, Pap.Services.WorkflowEngine.ActionTypes actionTaken, string notes, DateTime? completionDate)
        {
            Guid processInstanceID = wfService.GetProcessInstanceIDByEntity(loanID);
            wfService.Move(actionTaken, processInstanceID, RegistryInfo.UserID, notes, completionDate);
        }
    }
}
